package br.ufpe.cin.dsoa.qos.monitoring.service;

import java.util.Vector;

public class MonitoringConfigurationItem {

	// private Statement statetement;

	private final String operation;
	private final String attribute;
	private final String expression;
	private final double value;
	private final String statistic;
	private final double windowValue;
	private final String windowUnit;
	private String statement;
	private String statementName;
	private final Vector<SecondaryStatement> secondaryStatements;
	private final MonitoringConfiguration monitoringConfiguration;

	public MonitoringConfigurationItem(String operation, String attribute,
			String expression, double value, String statistic,
			String windowUnit, double windowValue, MonitoringConfiguration config) {

		this.operation = operation;
		this.attribute = attribute;
		this.expression = expression;
		this.value = value;
		this.windowUnit = windowUnit;
		this.windowValue = windowValue;
		this.statistic = statistic;
		this.monitoringConfiguration = config;
		this.secondaryStatements = new Vector<SecondaryStatement>();
		// this.createStatement();
		this.create();
	}

	public Vector<SecondaryStatement> getSecondaryStatements() {
		return secondaryStatements;
	}

	private void create() {

		if (this.operation != null) {
			if (this.attribute.equalsIgnoreCase("Accuracy") == true) {
				// Accuracy
				this.statementName = "VioXy - " + this.monitoringConfiguration.getClientId() + "-"
				+ this.monitoringConfiguration.getServiceId() + "-" +	this.attribute;
				
				this.statement = "select value from Accuracy" + "(serviceId="
				+ "'" + this.monitoringConfiguration.getServiceId()
				+ "'" + ", consumerId=" + "'"
				+ this.monitoringConfiguration.getClientId() + "'" +
				", operationName=" + "'" 
				+ this.operation + "'" +
				", value < " + this.value + ")";

				String countE = "select "
					+ "count(*) as countErrorBusinessException, serviceId, consumerId, operationName"
					+ " from ErrorEvent"
					+ "(serviceId="
					+ "'" + this.monitoringConfiguration.getServiceId() + "'"
					+ ", consumerId="
					+ "'" + this.monitoringConfiguration.getClientId()	+ "'"
					+ ", operationName=" 
					+ "'" + this.operation	+ "'"
					+ ", exceptionClass!=" +
					"'" +"java.io.IOException" + "'"
					+ ")"
					+ ".win:time_batch(" +this.windowValue+ " " + this.windowUnit+ ") group by serviceId, consumerId, operationName";

				String countEname = this.monitoringConfiguration.getClientId() + "-"
				+ this.monitoringConfiguration.getServiceId()
				+ "-" + this.attribute + "-" + "countE";

				String countR = "select "
					+ "count(*) as countRequestPerOperation, serviceId, consumerId, operationName"
					+ " from RequestEvent"
					+ "(serviceId="
					+ "'" + this.monitoringConfiguration.getServiceId() + "'"
					+ ", consumerId="
					+ "'" + this.monitoringConfiguration.getClientId()	+ "'"
					+ ", operationName=" 
					+ "'" + this.operation	+ "'"
					+ ")"
					+ ".win:time_batch(" +this.windowValue+ " " + this.windowUnit+ ") group by serviceId, consumerId, operationName";

				String countRname = this.monitoringConfiguration.getClientId() +"-"
				+ this.monitoringConfiguration.getServiceId()
				+ "-" + this.attribute + "-" + "countR";

				this.secondaryStatements.add(new SecondaryStatement(countE,
						countEname));
				this.secondaryStatements.add(new SecondaryStatement(countR,
						countRname));


			} else {
				// ResponseTime and Throughput - Aggregate
				if (this.statistic != null) {
					
					this.statementName = "VioXy - " + this.monitoringConfiguration
					.getClientId() +"-"
					+ this.monitoringConfiguration.getServiceId() + "-" + this.attribute;

					this.statement = "select " + this.statistic
					+ "(value) as value from " + this.attribute
					+ "(serviceId=" + "'"
					+ this.monitoringConfiguration.getServiceId()
					+ "'" + ", consumerId=" + "'"
					+ this.monitoringConfiguration.getClientId()
					+ "'" + ", operationName=" + "'"
					+ this.operation + "')"
					+ ".win:time_batch(" +this.windowValue+ " " + this.windowUnit+ ")" + " having not "
					+ this.statistic + "(value)" + this.expression
					+ this.value;
				}
				// ResponseTime and Throughput - no Aggreaged
				else {
					this.statementName = "VioXy - " + this.monitoringConfiguration
					.getClientId() +"-"
					+ this.monitoringConfiguration.getServiceId() + "-" + this.attribute;

					this.statement = "select value from " + this.attribute
					+ "(serviceId=" + 
					"'" + this.monitoringConfiguration.getServiceId() + "'" +
					", consumerId=" +
					"'"	+ this.monitoringConfiguration.getClientId() + "'"
					+ ", operationName=" + 
					"'"	+ this.operation + "'" +
					", value" + inverteOperador(this.expression) + this.value + ")";
				}
			}
		} else {
			// Availability
			
			this.statementName = "VioXy - " + this.monitoringConfiguration.getClientId() + "-"
			+ this.monitoringConfiguration.getServiceId() + "-" + this.attribute;
			
			this.statement = "select value from Availability" + "(serviceId="
			+ "'" + this.monitoringConfiguration.getServiceId()
			+ "'" + ", consumerId=" + "'"
			+ this.monitoringConfiguration.getClientId() + "'"
			+ ",value < " + this.value + ")";

			String countE = "select "
				+ "count(*) as countErrorIoException, serviceId, consumerId"   
				+ " from ErrorEvent"
				+ "(serviceId="
				+ "'"
				+ this.monitoringConfiguration.getServiceId()
				+ "'"
				+ ", consumerId="
				+ "'"
				+ this.monitoringConfiguration.getClientId()
				+ "'"
				+ ", exceptionClass in ('java.io.IOException', 'java.net.ConnectException', 'org.apache.cxf.binding.soap.SoapFault')"
				+ ")"
				+ ".win:time_batch(" +this.windowValue+ " " + this.windowUnit+ ") group by serviceId, consumerId";
			
			String countEname = this.monitoringConfiguration.getClientId() +"-"
			+ this.monitoringConfiguration.getServiceId() + "-" + this.attribute + "-" + "countE";

			String countR = "select "
				+ "count(*) as countRequest, serviceId, consumerId"
				+ " from RequestEvent"
				+ "(serviceId="
				+ "'"
				+ this.monitoringConfiguration.getServiceId()
				+ "'"
				+ ", consumerId="
				+ "'"
				+ this.monitoringConfiguration.getClientId()+ "'"
				+ ")"
				+ ".win:time_batch(" +this.windowValue+ " " + this.windowUnit+ ") group by serviceId, consumerId"; 

			String countRname = this.monitoringConfiguration.getClientId() + "-"
			+ this.monitoringConfiguration.getServiceId() + "-" + this.attribute + "-" + "countR";

			this.secondaryStatements.add(new SecondaryStatement(countE,
					countEname));
			this.secondaryStatements.add(new SecondaryStatement(countR,
					countRname));
		}
	}

	/*
	 * private void createStatement() { //select Select select = null; Statistic
	 * statistic = null; if (null != this.statisticName) { statistic = new
	 * Statistic(this.statisticName, "value"); select = new Select(statistic); }
	 * else { List<String> fields = new ArrayList<String>();
	 * fields.add("value"); select = new Select(fields); }
	 * 
	 * //from From from = new From(this.attribute); Clause clause1 = new
	 * Clause("serviceId","=", this.monitoringConfiguration.getServiceId());
	 * Clause clause2 = new Clause("clientId", "=",
	 * this.monitoringConfiguration.getClientId());
	 * from.getFilter().add(clause1); from.getFilter().add(clause2);
	 * if(this.operationName != null){ Clause clause3 = new
	 * Clause("operationName", "=", this.operationName);
	 * from.getFilter().add(clause3); }
	 * 
	 * this.statetement.setSelect(select); this.statetement.setFrom(from);
	 * 
	 * 
	 * //having if(this.statisticName != null){ HavingClause havingClause = new
	 * HavingClause(statistic, this.expression, this.value);
	 * this.statetement.setHavingClause(havingClause); }
	 * 
	 * //where else{ Clause whereClause = new Clause("value", this.expression,
	 * this.value); this.statetement.setWhereClause(whereClause); }
	 * 
	 * 
	 * 
	 * }
	 */

	public String getOperation() {
		return operation;
	}

	public String getAttribute() {
		return attribute;
	}

	public String getExpression() {
		return expression;
	}

	public double getValue() {
		return value;
	}

	public String getStatistic() {
		return statistic;
	}

	public String getStatementName() {
		return statementName;
	}

	public String getStatement() {
		return statement;
	}
	
	public double getWindowValue() {
		return windowValue;
	}

	public String getWindowUnit() {
		return windowUnit;
	}

	private String inverteOperador(String operador){
		
		String expressionInversa = null;
		
		if(operador.equalsIgnoreCase(">") == true){
			expressionInversa = "<"; 
		}
		
		if(operador.equalsIgnoreCase("<") == true){
			expressionInversa = ">"; 
		}
		
		return expressionInversa;
	}
	
}
